package org.hard.netty.c3;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.util.Iterator;

/**
 * @author: 王林博
 * @date: 2022年08月13日 15:58
 */
public class WriteServer {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel socketChannel = ServerSocketChannel.open();
        socketChannel.configureBlocking(false); // 非阻塞

        Selector selector = Selector.open();
        socketChannel.register(selector, SelectionKey.OP_ACCEPT);

        socketChannel.bind(new InetSocketAddress(8080));

        while (true){
            selector.select();
            final Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                final SelectionKey key = iterator.next();
                iterator.remove();

                if(key.isAcceptable()){ // 是否是客户端连接
                    final SocketChannel accept = socketChannel.accept();
                    accept.configureBlocking(false);
                    final SelectionKey register = accept.register(selector, 0, null);
                    register.interestOps(SelectionKey.OP_READ);
                    StringBuffer stringBuffer = new StringBuffer();
                    for (int i = 0; i < 10000000; i++) {
                        stringBuffer.append("a");
                    }
                    ByteBuffer buffer = Charset.defaultCharset().encode(stringBuffer.toString());
                    // 返回值表示写入的字节数
                    final int write = accept.write(buffer);
                    System.out.println(write);
                    if (buffer.hasRemaining()){
                        // 如果没写完 则注册一个可写事件
                        register.interestOps(register.interestOps() + SelectionKey.OP_WRITE);
                        // 把未写完的数据挂到key上面
                        register.attach(buffer);
                    }
//                    final int write = accept.write();
                }else if(key.isWritable()){
                    ByteBuffer buffer = (ByteBuffer) key.attachment();
                    SocketChannel sc = (SocketChannel) key.channel();
                    final int write = sc.write(buffer);
                    System.out.println(write);
                    if (!buffer.hasRemaining()){
                        // 需要清除buffer
                        key.attach(null);
                        // 不需要再关注可写事件
                        key.interestOps(key.interestOps() - SelectionKey.OP_WRITE);
                    }

                }
            }
        }

    }
}
